/**
 * 微信对接使用到的api接口
 */
import * as tools from 'src-ssr/util/common';
import rp from 'request-promise';
import fs from 'fs';

/**
 * 获取微信access_token
 * @param {number} tid 租户id
 * @returns access_token
 */
export const access_token = async (tid = 0) => {
  const config = await tools.getSystemConfig('wechat', tid);
  const { appid, secret, access_token_url } = config;
  if (!appid || !secret) {
    console.error('未配置appid, secret', appid, secret);
    return { result: 'fail', error: { message: '未配置appid, secret', appid, secret } };
  }

  const accessTokenData = { accessToken: '', expireTime: '' };

  // 本地有缓存access_token并且没过期，则读取，若条件不成立则重取
  if (fs.existsSync(`../wechat_access_token_${tid}.txt`)) {
    const fileData = JSON.parse(fs.readFileSync(`../wechat_access_token_${tid}.txt`));
    if (fileData.expireTime && fileData.expireTime < Date.now()) {
      accessTokenData.accessToken = fileData.accessToken;
      accessTokenData.expireTime = fileData.expireTime;
    }
  }

  if (!accessTokenData.accessToken || accessTokenData.expireTime < Date.now()) {
    // 取access_token 如果有 access_token 则从access_token里取
    if (access_token_url) { // 从第三方网站取
      try {
        const oriToken = JSON.parse(await rp(access_token_url));
        accessTokenData.accessToken = oriToken.token;
        accessTokenData.expireTime = oriToken.expire * 1000;
      } catch (err) {
        console.error('从第三方网站取access token出错', access_token_url, err);
        return { result: 'fail', error: { message: '从第三方网站取access token出错', access_token_url, err } }
      }
    } else { // 直接去微信取
      try {
        const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`;
        let ret = await rp(url);
        if (typeof ret === 'string') ret = JSON.parse(ret);

        if (ret.errcode) {
          console.error('获取微信access token失败,', ret);
          return { result: 'fail', error: { message: '获取微信access token失败', ret } };
        }
        accessTokenData.accessToken = ret.access_token;
        accessTokenData.expireTime = ret.expires_in * 1000 + Date.now();
      } catch (err) {
        console.error('获取微信access token发生异常', err);
        return { result: 'fail', error: { message: '获取微信access token发生异常', err } };
      }
    }

    try {
      fs.writeFileSync(`../wechat_access_token_${tid}.txt`, JSON.stringify(accessTokenData)); // 写入本地缓存文件
    } catch (err) {
      console.error('缓存access token出错', err, accessTokenData);
      return { result: 'fail', error: { message: '缓存access token出错', err, accessTokenData } };
    }
  }
  return { result: 'ok', accessTokenData };
};

/**
 * 获取jsapi_ticket
 * @param {number} tid 租户id
 */
export const jsapi_ticket = async (tid = 0) => {
  let accessToken = '';
  const ret = await access_token();
  if (ret.result === 'fail') {
    return ret;
  } else {
    accessToken = ret.accessTokenData.accessToken;
  }

  const jsapiTicketData = { ticket: '', expireTime: '' };

  // 本地有缓存ticket并且没过期，则读取，若条件不成立则重取
  if (fs.existsSync(`../wechat_jsapi_ticket_${tid}.txt`)) {
    const fileData = JSON.parse(fs.readFileSync(`../wechat_jsapi_ticket_${tid}.txt`));
    if (fileData.expireTime && fileData.expireTime < Date.now()) {
      jsapiTicketData.ticket = fileData.ticket;
      jsapiTicketData.expireTime = fileData.expireTime;
    }
  }

  if (!jsapiTicketData.ticket || jsapiTicketData.expireTime < Date.now()) {
    // 取jsapi_ticket
    try {
      const url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`;
      let ret = await rp(url);
      if (typeof ret === 'string') ret = JSON.parse(ret);

      if (ret.errcode) {
        console.error('获取微信jsapi ticket失败,', ret);
        return { result: 'fail', error: { message: '获取微信jsapi ticket失败', ret } };
      }
      jsapiTicketData.ticket = ret.ticket;
      jsapiTicketData.expireTime = ret.expires_in * 1000 + Date.now();
    } catch (err) {
      console.error('获取微信jsapi ticket发生异常', err);
      return { result: 'fail', error: { message: '获取微信jsapi ticket发生异常', err } };
    }

    try {
      fs.writeFileSync(`../wechat_jsapi_ticket_${tid}.txt`, JSON.stringify(jsapiTicketData)); // 写入本地缓存文件
    } catch (err) {
      console.error('缓存jsapi ticket出错', err, jsapiTicketData);
      return { result: 'fail', error: { message: '缓存jsapi ticket出错', err, jsapiTicketData } };
    }
  }
  return { result: 'ok', ticket: jsapiTicketData.ticket };
};

export default { access_token, jsapi_ticket };
